<template>
  <div class="private-chat-container">
    <div class="chat-header">
      <div class="user-avatars">
        <img :src="selfAvatar || 'https://placehold.co/30x30'" alt="Self Avatar" class="self-avatar" />
        <img :src="targetAvatar || 'https://placehold.co/30x30'" alt="Target Avatar" class="target-avatar" />
      </div>
      <span class="chat-title">{{ chatTitle }}</span>
    </div>
    <div class="message-list" ref="messageList">
        <div v-for="message in messages" :key="message.id" class="message-item" :class="message.sender === 'self' ? 'self-message' : 'other-message'">
        <!-- 对方消息：头像在左，气泡在右 -->
        <template v-if="message.sender === 'other'">
          <img :src="targetAvatar || 'https://placehold.co/30x30'" alt="Other Avatar" class="avatar" />
          <div class="message-content">
            <div v-if="message.text" class="text-message">{{ message.text }}</div>
            <img v-if="message.image" :src="message.image" alt="Message Media" class="image-message" @click="openMediaViewer(message.image)" />
            <video v-if="message.video" :src="message.video" controls class="video-message" @click="openMediaViewer(message.video)"></video>
          </div>
        </template>
        <!-- 自己消息：气泡在右，头像在右 -->
        <template v-else-if="message.sender === 'self'">
          <div class="message-content">
            <div v-if="message.text" class="text-message">{{ message.text }}</div>
            <img v-if="message.image" :src="message.image" alt="Message Media" class="image-message" @click="openMediaViewer(message.image)" />
            <video v-if="message.video" :src="message.video" controls class="video-message" @click="openMediaViewer(message.video)"></video>
          </div>
          <img :src="selfAvatar || 'https://placehold.co/30x30'" alt="Self Avatar" class="avatar" />
        </template>
      </div>
      <div v-if="showMenu" :style="{top: menuY + 'px', left: menuX + 'px'}" class="context-menu">
        <div @click="handleRecall">撤回</div>
        <div @click="handleDelete">删除</div>
      </div>
    </div>
    <div class="chat-input-area">
      <!-- 表情按钮 -->
      <button type="button" class="emoji-btn" @click="showEmojiPicker = !showEmojiPicker">
        <img src="https://img.icons8.com/material-outlined/96/lol--v1.png" alt="表情" width="24" height="24"/>
      </button>

      <!-- 表情选择器 -->
      <div v-if="showEmojiPicker" class="emoji-picker">
        <span v-for="emoji in emojis" :key="emoji" @click="insertEmoji(emoji)" class="emoji-item">{{ emoji }}</span>
      </div>

      <!-- 文件上传 -->
      <input
        type="file"
        ref="fileInput"
        multiple
        accept="image/*,video/*"
        @change="handleMediaUpload"
        style="display: none"
      >

      <!-- 媒体上传按钮 -->
      <button type="button" class="media-btn" @click="$refs.fileInput.click()">
        <img src="https://img.icons8.com/material-rounded/48/image.png" alt="图片" width="24" height="24"/>
      </button>

      <!-- 文本输入 -->
      <input
        type="text"
        v-model="newMessage"
        @keyup.enter="sendMessage"
        placeholder="参与讨论"
      />
      
      <!-- 发送按钮 -->
      <button @click="sendMessage">发送</button>
    </div>
  </div>
  
  <!-- 媒体查看器 -->
  <MediaViewer 
    v-if="showMediaViewer" 
    :mediaList="mediaViewerList" 
    :initialIndex="mediaViewerIndex" 
    @close="closeMediaViewer" 
  />
</template>

  <script>
  import axios from 'axios';
  import MediaViewer from '../activity/MediaViewer.vue';

  export default {
    name: 'PrivateChat',
    components: {
      MediaViewer
    },
    props: {
      currentUserId: { type: Number, required: true }, // 登录用户
      targetUserId: { type: Number, required: true }   // 聊天对象
    },
    data() {
      return {
        messages: [],
        newMessage: '',
        showEmojiPicker: false,
        emojis: ['😀','😂','🤣','😊','🤔','😍','😘','🥰','💕','👍','👎','🔥','🎉','😁',
        '😊','😑','😭','😨','😱','😡','😵','🤡','💩','👀','🍺'],
        chatTitle: '加载中...',
        showMenu: false,
        menuX: 0,
        menuY: 0,
        selectedMessage: null,
        selectedIndex: null,
        mediaBaseUrl: 'http://localhost:8082',
        // MediaViewer相关数据
        showMediaViewer: false,
        mediaViewerList: [],
        mediaViewerIndex: 0,
        // 头像相关
        selfAvatar: '',
        targetAvatar: '',
        // WebSocket相关
        wsConnection: null,
        wsReconnectTimer: null
      };
    },
    watch: {
      targetUserId(newVal) {
        this.loadMessages();
        this.fetchUserName(newVal);
      }
    },
    mounted() {
      console.log('PrivateChat mounted, userId:', this.targetUserId, '类型:', typeof this.targetUserId);
      this.loadMessages();
      this.fetchUserName(this.targetUserId);
      // 监听点击关闭表情选择器
      document.body.addEventListener('click', this.handleBodyClick, true);
      // 建立WebSocket连接
      this.setupWebSocket();
    },
    beforeUnmount() {
      document.body.removeEventListener('click', this.handleBodyClick, true);
      // 关闭WebSocket连接
      this.closeWebSocket();
    },
    methods: {
      /**
       * 打开媒体查看器
       * @param {string} mediaUrl - 媒体URL
       */
      openMediaViewer(mediaUrl) {
        // 收集所有媒体消息
        this.mediaViewerList = [];
        this.messages.forEach(message => {
          if (message.image) {
            this.mediaViewerList.push(message.image);
          } else if (message.video) {
            this.mediaViewerList.push(message.video);
          }
        });
        
        // 设置当前查看的媒体索引
        this.mediaViewerIndex = this.mediaViewerList.indexOf(mediaUrl);
        
        // 显示媒体查看器
        this.showMediaViewer = true;
      },
      
      /**
       * 关闭媒体查看器
       */
      closeMediaViewer() {
        this.showMediaViewer = false;
      },
      
      /**
       * 获取完整的媒体文件URL
       * @param {string} url - 媒体文件URL
       */
      getFullMediaUrl(url) {
        if (!url) return '';
        // 移除URL两端的空格和可能存在的反引号
        const cleanUrl = url.trim().replace(/^`|`$/g, '').trim();
        if (cleanUrl.startsWith('http')) {
          return cleanUrl;
        }
        return `${this.mediaBaseUrl}${cleanUrl}`;
      },
      /**
       * 获取用户昵称
       * @param {number} userId - 用户ID
       */
      async fetchUserName(userId) {
        try {
          console.log('fetchUserName 调用，userId:', userId, '类型:', typeof userId);
          const url = `/api/user/nickname/${userId}`;
          console.log('请求URL:', url);
          const response = await axios.get(url);
          console.log('fetchUserName 响应:', response.data);
          const userName = response.data.nickname || response.data.data || response.data;
          this.chatTitle = userName;
          
          // 从localStorage获取当前用户信息
          const userStr = localStorage.getItem('user');
          if (userStr) {
            try {
              const user = JSON.parse(userStr);
              // 获取当前用户头像
              if (user && user.id) {
                // 先尝试从localStorage获取avatar
                if (user.avatar && user.avatar.trim()) {
                  this.selfAvatar = user.avatar.trim();
                } else {
                  // 如果localStorage中没有avatar，则通过API获取
                  axios.get(`http://localhost:8084/api/user/${user.id}`)
                    .then(response => {
                      if (response.data && response.data.avatar) {
                        this.selfAvatar = response.data.avatar.trim();
                      } else {
                        this.selfAvatar = 'https://placehold.co/30x30';
                      }
                      console.log('当前用户头像:', this.selfAvatar);
                    })
                    .catch(error => {
                      console.error('获取当前用户头像失败:', error);
                      this.selfAvatar = 'https://placehold.co/30x30';
                    });
                }
              } else {
                this.selfAvatar = 'https://placehold.co/30x30';
              }
            } catch (error) {
              console.error('解析当前用户信息失败:', error);
              this.selfAvatar = 'https://placehold.co/30x30';
            }
          } else {
            this.selfAvatar = 'https://placehold.co/30x30';
          }
          
          // 获取目标用户信息
          try {
            // 通过API获取目标用户信息
            axios.get(`http://localhost:8084/api/user/${userId}`)
              .then(response => {
                if (response.data && response.data.avatar) {
                  this.targetAvatar = response.data.avatar.trim();
                } else {
                  this.targetAvatar = 'https://placehold.co/30x30';
                }
                console.log('目标用户头像:', this.targetAvatar);
              })
              .catch(error => {
                console.error('获取目标用户信息失败:', error);
                this.targetAvatar = 'https://placehold.co/30x30';
              });
          } catch (error) {
            console.error('获取目标用户信息失败:', error);
            this.targetAvatar = 'https://placehold.co/30x30';
          }
          
          console.log('userId:', userId, 'userName:', userName, 'raw:', response.data);
        } catch (error) {
          console.error('Failed to fetch user name:', error.response?.status, error.response?.data);
          console.error('错误详情:', error);
          this.chatTitle = '未知用户';
        }
      },
      /**
       * 加载历史消息
       * @param {number} userId - 用户ID
       */
      async loadMessages() {
        const senderId = this.currentUserId;
        const userId = this.targetUserId;
        const res = await axios.get(`/api/messages/history/${senderId}/${userId}`);

        if (res.data && res.data.code === 200 && Array.isArray(res.data.data)) {
          this.messages = res.data.data.map(msg => {
            if (msg.type === 0) {
              return { id: msg.id, sender: msg.senderId === senderId ? 'self' : 'other', text: msg.content, image: '', video: '' };
            } else if (msg.type === 1) {
              return { id: msg.id, sender: msg.senderId === senderId ? 'self' : 'other', text: '', image: this.getFullMediaUrl(msg.mediaUrl), video: '' };
            } else if (msg.type === 2) {
              return { id: msg.id, sender: msg.senderId === senderId ? 'self' : 'other', text: '', image: '', video: this.getFullMediaUrl(msg.mediaUrl) };
            }
            return { id: msg.id, sender: msg.senderId === senderId ? 'self' : 'other', text: '', image: '', video: '' };
          });
        } else {
          console.error('消息数据格式错误:', res.data);
          this.messages = [];
        }
      },
      /**
       * 插入表情到输入框
       * @param {string} emoji - 表情符号
       */
      insertEmoji(emoji) {
        this.newMessage += emoji;
      },
      /**
       * 发送文本消息
       */
      async sendMessage() {
        if (!this.newMessage.trim()) return;
        const messageObj = {
          senderId: this.currentUserId,
          receiverId: this.targetUserId,
          content: this.newMessage,
          type: 0 // 文本
        };
        try {
          const res = await axios.post('/api/messages/send', messageObj);
          if (res.data && res.data.code === 200 && res.data.data && res.data.data.id) {
            this.messages.push({
              id: res.data.data.id,
              sender: 'self',
              text: this.newMessage,
              image: '',
              video: ''
            });
            this.newMessage = '';
            this.showEmojiPicker = false;
          } else {
            alert('消息发送失败');
          }
        } catch (e) {
          alert('消息发送异常');
          console.error(e);
        }
      },
      /**
       * 处理点击表情选择器外部区域关闭
       */
      handleBodyClick(event) {
        if (
          this.showEmojiPicker &&
          !document.querySelector('.emoji-picker')?.contains(event.target) &&
          !document.querySelector('.emoji-btn')?.contains(event.target)
        ) {
          this.showEmojiPicker = false;
        }
      },
      /**
       * 消息右键菜单显示
       * @param {Object} message - 当前消息对象
       * @param {Event} event - 右键事件对象
       * @param {number} index - 消息索引
       */
      onMessageRightClick(message, event, index) {
        if (message.sender !== 'self') return;
        this.selectedMessage = message;
        this.selectedIndex = index;
        this.menuX = event.clientX;
        this.menuY = event.clientY;
        this.showMenu = true;
        document.body.addEventListener('click', this.handleMenuClose, true);
        console.log('撤回消息对象:', this.selectedMessage, '当前用户ID:', this.currentUserId);
      },
      /**
       * 隐藏右键菜单
       */
      handleMenuClose() {
        this.showMenu = false;
        document.body.removeEventListener('click', this.handleMenuClose, true);
      },
      /**
       * 撤回消息
       */
      async handleRecall() {
        if (!this.selectedMessage || !this.selectedMessage.id || !this.currentUserId) {
          alert('撤回参数异常（消息ID或用户ID缺失）');
          this.showMenu = false;
          return;
        }
        const now = new Date();
        const sendTime = new Date(this.selectedMessage.sendDate);
        if ((now - sendTime) / 1000 > 120) {
          alert('已超过两分钟无法撤回');
          this.showMenu = false;
          return;
        }
        try {
          const res = await axios.post(`/api/messages/recall/${this.selectedMessage.id}/${this.currentUserId}`);
          if (res.data && res.data.code === 200 && res.data.data) {
            this.messages.splice(this.selectedIndex, 1);
          } else {
            alert(res.data.message || '撤回失败');
          }
        } catch (e) {
          alert('撤回异常');
        }
        this.showMenu = false;
      },
      /**
       * 删除消息
       */
      async handleDelete() {
        try {
          const res = await axios.post(`/api/messages/delete/${this.selectedMessage.id}/${this.currentUserId}`);
          if (res.data && res.data.code === 200 && res.data.data) {
            this.messages.splice(this.selectedIndex, 1);
          } else {
            alert('删除失败');
          }
        } catch (e) {
          alert('删除异常');
        }
        this.showMenu = false;
      },
      /**
       * 处理媒体文件上传
       * @param {Event} event - 文件选择事件
       */
      async handleMediaUpload(event) {
        const files = event.target.files;
        if (!files || files.length === 0) return;

        const formData = new FormData();
        for (let i = 0; i < files.length; i++) {
          formData.append('files', files[i]);
        }

        try {
          const res = await axios.post('/api/messages/upload', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
          });
          if (res.data && res.data.code === 200 && Array.isArray(res.data.data)) {
            for (let i = 0; i < files.length; i++) {
              const file = files[i];
              const url = res.data.data[i];
              const isImage = file.type.startsWith('image/');
              const isVideo = file.type.startsWith('video/');
              const messageObj = {
                senderId: this.currentUserId,
                receiverId: this.targetUserId,
                content: '',
                type: isImage ? 1 : (isVideo ? 2 : 1),
                mediaUrl: url
              };
              await axios.post('/api/messages/send', messageObj);
              this.messages.push({
                sender: 'self',
                text: '',
                image: isImage ? this.getFullMediaUrl(url) : '',
                video: isVideo ? this.getFullMediaUrl(url) : ''
              });
            }
          } else {
            alert('文件上传失败');
          }
        } catch (e) {
          alert('文件上传异常');
          console.error(e);
        }
        this.$refs.fileInput.value = '';
      },
      
      /**
       * 建立WebSocket连接
       */
      setupWebSocket() {
        // 关闭已有连接
        this.closeWebSocket();
        
        const userId = this.currentUserId;
        if (!userId) {
          console.error('无法建立WebSocket连接：用户ID为空');
          return;
        }
        
        // 创建WebSocket连接
        const wsUrl = `ws://localhost:8082/websocket/chat/${userId}`;
        this.wsConnection = new WebSocket(wsUrl);
        
        // 连接建立时的处理
        this.wsConnection.onopen = () => {
          console.log('私信WebSocket连接已建立');
          // 连接成功后立即获取一次最新消息
          this.loadMessages();
        };
        
        // 接收消息的处理
        this.wsConnection.onmessage = (event) => {
          console.log('私信收到WebSocket消息:', event.data);
          try {
            const data = JSON.parse(event.data);
            
            // 处理新消息通知
            if (data.type === 'NEW_MESSAGE') {
              // 如果消息涉及当前聊天对象，刷新消息列表
              if (data.senderId === this.targetUserId || data.receiverId === this.targetUserId) {
                this.loadMessages();
              }
            } 
            // 处理消息撤回通知
            else if (data.type === 'MESSAGE_RECALLED') {
              if (data.messageId) {
                // 从消息列表中移除被撤回的消息
                const index = this.messages.findIndex(msg => msg.id === data.messageId);
                if (index !== -1) {
                  this.messages.splice(index, 1);
                }
              }
            }
            // 处理会话列表更新
            else if (Array.isArray(data)) {
              // 检查是否有当前聊天对象的新消息
              const currentChat = data.find(session => session.friendId === this.targetUserId);
              if (currentChat) {
                // 刷新消息列表
                this.loadMessages();
              }
            }
          } catch (error) {
            console.error('解析WebSocket消息失败:', error);
          }
        };
        
        // 连接关闭时的处理
        this.wsConnection.onclose = () => {
          console.log('私信WebSocket连接已关闭');
          // 清除旧的重连定时器
          if (this.wsReconnectTimer) {
            clearTimeout(this.wsReconnectTimer);
          }
          // 尝试重新连接
          this.wsReconnectTimer = setTimeout(() => {
            this.setupWebSocket();
          }, 3000);
        };
        
        // 连接错误时的处理
        this.wsConnection.onerror = (error) => {
          console.error('私信WebSocket错误:', error);
          // 连接失败时尝试使用HTTP请求获取数据
          this.loadMessages();
        };
      },
      
      /**
       * 关闭WebSocket连接
       */
      closeWebSocket() {
        if (this.wsConnection && this.wsConnection.readyState === WebSocket.OPEN) {
          this.wsConnection.close();
        }
        
        // 清除重连定时器
        if (this.wsReconnectTimer) {
          clearTimeout(this.wsReconnectTimer);
          this.wsReconnectTimer = null;
        }
      }
    }
  };
  </script>

  <style scoped>
  .private-chat-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: #f7f7f7;
    border-left: 1px solid #ebebeb;
  }

  .chat-header {
    padding: 15px 20px;
    border-bottom: 1px solid #ebebeb;
    display: flex;
    align-items: center;
    font-weight: bold;
    font-size: 1.1em;
    color: #333;
  }
  
  .user-avatars {
    display: flex;
    margin-right: 15px;
  }
  
  .self-avatar, .target-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 2px solid #fff;
  }
  
  .target-avatar {
    margin-left: -10px;
  }
  
  .chat-title {
    margin-left: 5px;
  }

  .message-list {
    flex-grow: 1;
    padding: 20px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
  }

  .message-item {
    display: flex;
    margin-bottom: 15px;
    align-items: flex-end;
  }

  .avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    margin: 0 10px;
    flex-shrink: 0;
  }

  .message-content {
    max-width: 60%;
    padding: 10px 15px;
    border-radius: 18px;
    word-wrap: break-word;
  }

  .message-media {
    max-width: 200px;
    max-height: 200px;
    width: auto;
    height: auto;
    border-radius: 8px;
    margin-top: 8px;
  }

  .image-message, .video-message {
    max-width: 400px;
    max-height: 400px;
    width: auto;
    height: auto;
    border-radius: 8px;
    margin-top: 8px;
    cursor: pointer;
    display: block;
    transition: transform 0.2s ease;
  }

  .image-message:hover, .video-message:hover {
    transform: scale(1.02);
  }

  .video-message {
    background: #000;
  }

  .video-message::-webkit-media-controls-volume-slider,
  .video-message::-webkit-media-controls-mute-button,
  .video-message::-webkit-media-controls-fullscreen-button,
  .video-message::-webkit-media-controls-playback-rate-button,
  .video-message::-webkit-media-controls-picture-in-picture-button {
    display: none !important;
  }

  .self-message {
    justify-content: flex-end;
  }

  .other-message {
    justify-content: flex-start;
  }

  .self-message .message-content {
    background-color: #bababa;
    color: #333;
    border-bottom-right-radius: 5px;
  }

  .other-message .message-content {
    background-color: #fff;
    color: #333;
    border: 1px solid #ebebeb;
    border-bottom-left-radius: 5px;
  }

  .chat-input-area {
    display: flex;
    padding: 15px 20px;
    border-top: 1px solid #ebebeb;
    background-color: #fff;
    position: relative;
  }

  .chat-input-area .emoji-btn {
    background: none;
    border: none;
    padding: 0 5px;
    cursor: pointer;
  }

  .chat-input-area .emoji-btn:hover {
    opacity: 0.7;
  }

  .chat-input-area .emoji-picker {
    position: absolute;
    bottom: 60px;
    left: 10px;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 5px;
    display: flex;
    flex-wrap: wrap;
    max-width: 200px;
    max-height: 200px;
    overflow-y: auto;
    z-index: 100;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  }

  .chat-input-area .emoji-item {
    font-size: 20px;
    cursor: pointer;
    padding: 2px 4px;
    border-radius: 4px;
    transition: background-color 0.2s;
  }

  .chat-input-area .emoji-item:hover {
    background-color: #f0f0f0;
  }

  .chat-input-area .media-btn {
    background: none;
    border: none;
    padding: 0 5px;
    cursor: pointer;
  }

  .chat-input-area .media-btn:hover {
    opacity: 0.7;
  }

  .chat-input-area input[type="text"] {
    flex-grow: 1;
    border: 1px solid #ebebeb;
    border-radius: 20px;
    padding: 10px 15px;
    font-size: 0.95em;
    margin-right: 10px;
    outline: none;
  }

  .chat-input-area button {
    background-color: #000000;
    color: white;
    border: none;
    border-radius: 20px;
    padding: 10px 20px;
    cursor: pointer;
    font-size: 0.95em;
    transition: background-color 0.2s;
  }

  .chat-input-area button:hover {
    background-color: #333333;
  }

  .context-menu {
    position: fixed;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    z-index: 9999;
    min-width: 50px;
    font-size: 10px;
  }
  .context-menu > div {
    padding: 3px 8px;
    cursor: pointer;
    color: #333;
  }
  .context-menu > div:hover {
    background: #f5f5f5;
  }
  </style>
